import Joi from 'joi';
import Boom from '@hapi/boom';
import fetch from 'fermionjs/lib/fetch';
import debugCheck from '@kuiper-helpers/debug-check';
import pkg from '../../../package.json';
import errorCodesBuilder from '../helpers/errorCodesBuilder';
import urlPathConcat from '@kuiper-helpers/url-path-concat/dist';
const { name } = pkg;

const errorCodes = errorCodesBuilder();

export const qrcode = {
	tags: ['api', 'alert', 'wechat'],
	description: '获取微信绑定二维码',
	auth: debugCheck('disable-open-api-auth')
		? false
		: {
				mode: 'required',
				// access: {
				// 	// 只允许使用 URL Token 访问
				// 	entity: 'app',
				// },
		  },

	validate: {
		params: Joi.object({
			userId: Joi.string().description('用户UID'),
		}),
	},

	response: {
		schema: Joi.object({
			image: Joi.string().description('二维码图片。Base64编码'),
			mime: Joi.string().default('image/jpeg').description('图片格式'),
			url: Joi.string().description('二维码URL'),
		}).label('Response'),
	},

	async handler(request) {
		const {
			params: { userId },
			server: {
				app: {
					model: { User },
					config: {
						[name]: { casAppId, serviceApi, token },
					},
				},
			},
			auth: {
				credentials: { uid, permissionMap },
			},
		} = request;

		let user;
		try {
			user = await User.findOne({
				_id: permissionMap[`auth\x01editUser\x010`] ? userId : uid,
			});
			if (!user) {
				request.log.warn({ userId }, '绑定微信:没有找到对应用户');
				throw new Error('Invalid userId');
			}
		} catch (err) {
			const error = errorCodes['[0A][绑定微信]查询对应用户信息失败'].from(err);
			request.log.error({ error }, error.rawMessage);
			throw Boom.boomify(error);
		}

		request.log.audit(
			{
				actionType: 'create',
				module: 'alert',
				actionMessage: '获取微信绑定二维码',
				detail: `${user.username}获取微信绑定二维码`,
			},
			`[${user.username}]获取微信绑定二维码`
		);

		let imageUrl;
		try {
			const response = await fetch(
				urlPathConcat(serviceApi, '/api/v2/users/cas'),
				{
					method: 'POST',
					body: JSON.stringify({
						url: `/accounts/${casAppId}/get_qrcode_url/`,
						body: {
							username: user.username,
						},
					}),
					headers: {
						cookie: `token=${token}`,
						'content-type': 'application/json',
					},
				}
			).then(resp => {
				if (!resp || resp.status !== 'success') {
					request.log.error({ error: resp.message }, resp.message);
					throw Boom.badRequest(resp.message);
				}
				return resp.data;
			});
			imageUrl = response.qrcode_url;
		} catch (err) {
			const error = errorCodes[
				err.message === 'user bind other wx'
					? '[0A][绑定微信]用户已绑定微信'
					: '[0A][绑定微信]请求二维码URL失败'
			].from(err);
			request.log.error({ error }, error.rawMessage);
			throw Boom.badRequest(error.detail);
		}

		let image;
		try {
			image = await fetch(imageUrl, { responseType: 'raw' }).then(x =>
				x.buffer()
			);
			image = image.toString('base64');
		} catch (err) {
			const error = errorCodes['[0A][绑定微信]读取二维码失败'].from(err);
			request.log.error({ error }, error.rawMessage);
			throw Boom.boomify(error);
		}

		return {
			image,
			mime: 'image/jpeg',
			url: imageUrl,
		};
	},
};

export const bindCheck = {
	tags: ['api', 'alert', 'wechat'],
	description: '检查微信绑定状态',
	auth: debugCheck('disable-open-api-auth')
		? false
		: {
				mode: 'required',
				// access: {
				// 	// 只允许使用 URL Token 访问
				// 	entity: 'app',
				// },
		  },

	validate: {
		params: Joi.object({
			userId: Joi.string().description('用户UID'),
		}),
	},

	response: {
		schema: Joi.object({
			wx_openid: Joi.string().allow(null),
			message: Joi.string(),
		}).label('Response'),
	},

	async handler(request) {
		const {
			params: { userId },
			server: {
				app: {
					model: { User },
					config: {
						[name]: { casAppId, serviceApi, token },
					},
				},
			},
			auth: {
				credentials: { uid, permissionMap },
			},
		} = request;
		request.log.info('检查微信绑定状态');

		let user;
		try {
			user = await User.findOne({
				_id: permissionMap[`auth\x01editUser\x010`] ? userId : uid,
			});
			if (!user) {
				request.log.warn({ userId }, '检查微信绑定状态:没有找到对应用户');
				return { wx_openid: null, message: '未绑定微信' };
			}
		} catch (err) {
			const error = errorCodes[
				'[0A][检查微信绑定状态]查询对应用户信息失败'
			].from(err);
			request.log.error({ error }, error.rawMessage);
			throw Boom.boomify(error);
		}

		let response;
		try {
			const response = await fetch(
				urlPathConcat(serviceApi, '/api/v2/users/cas'),
				{
					method: 'POST',
					body: JSON.stringify({
						url: `/accounts/${casAppId}/check_wx_bind/`,
						body: {
							username: user.username,
						},
					}),
					headers: {
						cookie: `token=${token}`,
						'content-type': 'application/json',
					},
				}
			).then(resp => {
				if (!resp || resp.status !== 'success') {
					request.log.error({ error: resp.message }, resp.message);
					throw Boom.badRequest(resp.message);
				}
				return resp.data;
			});
			// eslint-disable-next-line camelcase
			if (response?.wx_openid) {
				if (!user.wechat) user.wechat = {};
				user.wechat.wx_openid = response.wx_openid;
				await user.save();
			}

			request.log.audit(
				{
					actionType: 'update',
					module: 'alert',
					actionMessage: '更新微信',
					detail: `在告警设置中绑定微信。`,
				},
				`[${user.username}]解绑告警微信`
			);
		} catch (err) {
			if (err.message === 'wx_openid is null') {
				return { wx_openid: null, message: '未绑定微信' };
			} else if (err.message === 'username is wrong') {
				return { wx_openid: null, message: '未绑定微信' };
			} else {
				const error = errorCodes['[0A][检查微信绑定状态]请求失败'].from(err);
				request.log.error({ error, casAppId }, error.rawMessage);
				throw Boom.boomify(error);
			}
		}

		return { ...response, message: '已绑定微信' };
	},
};

export const unbind = {
	tags: ['api', 'alert', 'wechat'],
	description: '解绑告警微信',
	auth: debugCheck('disable-open-api-auth')
		? false
		: {
				mode: 'required',
				// access: {
				// 	// 只允许使用 URL Token 访问
				// 	entity: 'app',
				// },
		  },

	validate: {
		params: Joi.object({
			userId: Joi.string().description('用户UID'),
		}),
	},

	response: {
		schema: Joi.object({
			message: Joi.string(),
		}).label('Response'),
	},

	async handler(request) {
		const {
			params: { userId },
			server: {
				app: {
					model: { User },
					config: {
						[name]: { casAppId, serviceApi, token },
					},
				},
			},
			auth: {
				credentials: { uid, permissionMap },
			},
		} = request;

		let user;
		try {
			user = await User.findOne({
				_id: permissionMap[`auth\x01editUser\x010`] ? userId : uid,
			});
			if (!user) {
				request.log.warn({ userId }, '解绑微信:没有找到对应用户');
				return { message: '解绑成功' };
			}
		} catch (err) {
			const error = errorCodes['[0A][解绑微信]查询对应用户信息失败'].from(err);
			request.log.error({ error }, error.rawMessage);
			throw Boom.boomify(error);
		}
		const nickname = user?.wechat?.nickname || '';

		try {
			const response = await fetch(
				urlPathConcat(serviceApi, '/api/v2/users/cas'),
				{
					method: 'POST',
					body: JSON.stringify({
						url: `/accounts/${casAppId}/wx_unbind/`,
						body: {
							username: user.username,
						},
					}),
					headers: {
						cookie: `token=${token}`,
						'content-type': 'application/json',
					},
				}
			).then(resp => {
				if (!resp || resp.status !== 'success') {
					request.log.error({ error: resp.message }, resp.message);
					throw Boom.badRequest(resp.message);
				}
				return resp.data;
			});
			console.log(response);
		} catch (err) {
			if (err.message !== 'user not bind wx') {
				const error = errorCodes['[0A][绑定微信]解绑微信失败'].from(err);
				request.log.error({ error, casAppId }, error.rawMessage);
				throw Boom.boomify(error);
			} else if (err.message === 'username is wrong') {
				request.log.warn(
					{ userId, username: user.username },
					'解绑微信:没有找到对应用户'
				);
			} else {
				request.log.warn('解绑微信:用户没有绑定微信');
			}
		}

		try {
			user.wechat = null;
			user.save();
		} catch (err) {
			const error = errorCodes['[0A][绑定微信]更新用户信息失败'].from(err);
			request.log.error({ error }, error.rawMessage);
			throw Boom.boomify(error);
		}

		request.log.audit(
			{
				actionType: 'update',
				module: 'alert',
				actionMessage: '更新微信',
				detail: `在告警设置中解绑微信${nickname}。`,
			},
			`[${user.username}]解绑告警微信`
		);

		return { message: '解绑成功' };
	},
};
